﻿//-------------------------------------------------------
// Copyright (c) 
// All rights reserved.
//
// File Name: MutexLock.h
// File Des: 实现自动锁保护的封装
// File Summary: 使用方式：Mutex m_mutex; Mutex::Lock lock(m_mutex);
// 使用方式： AutoLockUnlockHelperT<decltype(m_sqid2listeners)>
// autolock(&m_sqid2listeners);
// Cur Version: 2.0
// Author:zeron
// Data:2018-3-31 History: 		<Author>	<Time> <Version> <Des>
//      zeron		2018-3-31 1.0
//      zeron		2021-6-9 	2.0
//-------------------------------------------------------

#pragma once
#include <windows.h>

template <typename T> class AutoLockUnlockHelperT {
public:
  AutoLockUnlockHelperT(T *mutex) : _pmutex(mutex), _bUnlocked(false) {
    _pmutex->lock();
  }

  ~AutoLockUnlockHelperT() { Unlock(); }

  void Unlock() {
    if (!_bUnlocked)
      _pmutex->unlock();
    _bUnlocked = true;
  }

private:
  AutoLockUnlockHelperT(const AutoLockUnlockHelperT &);
  AutoLockUnlockHelperT &operator=(const AutoLockUnlockHelperT &);
  T *_pmutex;
  bool _bUnlocked;
};

template <typename T> class AutoLockT {
public:
  AutoLockT(const T &mutex) : _mutex(mutex) { _mutex.lock(); }

  ~AutoLockT() { _mutex.unlock(); }

private:
  // Not implemented; prevents accidental use.
  AutoLockT(const AutoLockT &);
  AutoLockT &operator=(const AutoLockT &);

  const T &_mutex;
};

class Mutex {
public:
  typedef AutoLockT<Mutex> Lock;

  inline Mutex() { ::InitializeCriticalSection(&m_sesion); }
  ~Mutex() { ::DeleteCriticalSection(&m_sesion); }

private:
  // noncopyable
  Mutex(const Mutex &);
  void operator=(const Mutex &);

public:
  void lock(void) const { ::EnterCriticalSection(&m_sesion); }

  void unlock(void) const { ::LeaveCriticalSection(&m_sesion); }

  bool tryLock() const {
    return (TRUE == ::TryEnterCriticalSection(&m_sesion));
  }

public:
  mutable CRITICAL_SECTION m_sesion;
};
